/**
 * 
 * 
 */
package com.cjfather.redis.steam.annotation.serializer;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;

import com.alibaba.fastjson2.JSON;
import com.cjfather.redis.steam.controller.PropellingInfo;

import io.fury.Fury;
import io.fury.Language;
import io.fury.serializer.CompatibleMode;

/**
 * @author: todd
 * @date:   2023年8月30日
 */
public class FurySerializer implements RedisSerializer<Object>{
	
	private final Charset charset;
	
//	ThreadSafeFury fury = Fury.builder()
	public final static Fury fury = Fury.builder()
		    .withLanguage(Language.JAVA)
		    //开启共享引用/循环引用支持，不需要的话建议关闭，性能更快
		    .withRefTracking(true)
		    // 允许序列化未注册类型
		    // .withClassRegistrationRequired(false)
		    // 开启int/long压缩，减少序列化数据大小，无该类需求建议关闭，性能更好
		    // .withNumberCompressed(true)
		    .withCompatibleMode(CompatibleMode.SCHEMA_CONSISTENT)
		    // 开启类型前后兼容，允许序列化和反序列化字段不一致，无该类需求建议关闭，性能更好
		    // .withCompatibleMode(CompatibleMode.COMPATIBLE)
		    // 开启异步多线程编译
		    .withAsyncCompilation(true)
		    .requireClassRegistration(false)
//		    .buildThreadSafeFury();
		    .build();

	public FurySerializer() {
		this(StandardCharsets.UTF_8);
	}

	public FurySerializer(Charset charset) {
		Assert.notNull(charset, "Charset must not be null!");
		this.charset = charset;
		fury.register(PropellingInfo.class);
	}

	@Override
	public byte[] serialize(Object object) throws SerializationException {
		if(object == null) {
			return new byte[0];
		}
//		//fury
//		return fury.serialize(object);
//		//json
		if(object instanceof String) {
			return object.toString().getBytes(charset);
		} else {
			String string = JSON.toJSONString(object);
			return string.getBytes(charset);
		}
	}

	@Override
	public Object deserialize(byte[] bytes) throws SerializationException {
//		return bytes == null ? null : fury.deserialize(bytes);
		return bytes == null ? null : new String(bytes, this.charset);
	}

}
